package org.alesv.common.collection;

import java.util.ArrayList;
import java.util.List;

public class TrieNode {

	TrieNode[] next; // index 0 reserved for terminator value
	char value;

	public TrieNode(char object) {
		value = object;
		next = new TrieNode[27];
	}

	public TrieNode() {
		next = new TrieNode[27];
	}

	public void setValue(char ch) {
		value = ch;
	}

	public char getValue() {
		return value;
	}

	public TrieNode getNext(char ch) {
		return next[Trie.getIndex(ch)];
	}

	public TrieNode getNext(int i) {
		if (!(i > 0 && i <= 27))
			return null;
		return next[i];
	}

	public boolean setNext(char ch, TrieNode node) {
		next[Trie.getIndex(ch)] = node;
		return true;
	}

	public TrieNode getTerminator() {
		return next[0];
	}

	// marks terminator as non null (the TrieNode is just a placeholder)
	public void setTerminator() {
		next[0] = new TrieNode();
	}

	public boolean isTerminatorSet() {
		return next[0] != null;
	}

	public String toString() {

		String string = "";

		for (int i = 0; i < 27; i++)
			if (next[i] == null)
				string += " null";
			else
				string += " +++";
		return string;
	}

	public List<String> toList(String prefix, List<String> previous) {
		List<String> myPart = new ArrayList<String>();

		for (int i = 1; i < 27; i++) {
			if (next[i] != null)
				myPart.addAll(this.getNext(i).toList(
						prefix + ((char) (i + 'A' - 1)), previous));
		}

		if (this.isTerminatorSet()) {
			myPart.add(prefix);
		}

		return myPart;
	}

	public TrieNode clone() {
		TrieNode clonedTrieNode = new TrieNode();
		try {
			clonedTrieNode.setValue(this.getValue());
			for (TrieNode nextTrieNode : next) {
				if (nextTrieNode != null) {
					if (Trie.getIndex(nextTrieNode.getValue()) > 0) {
						clonedTrieNode.setNext(nextTrieNode.getValue(),
								nextTrieNode.clone());
					} else {
						clonedTrieNode.setTerminator();
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return clonedTrieNode;
	}

	public String getFirstWord() {
		String word = "";
		if (Character.isLetter(this.getValue())) {
			word += this.getValue();
		}

		if (getTerminator() == null && this.next != null) {
			for (int i = 1; i < this.next.length; i++) {
				if (this.next[i] != null) {
					word += this.next[i].getFirstWord();
					break;
				}
			}
		}

		return word;
	}

	public String getFirstWord(int minSize) {
		String word = "";
		if (Character.isLetter(this.getValue())) {
			word += this.getValue();
		}

		if (getTerminator() == null && this.next != null) {
			for (int i = 1; i < this.next.length; i++) {
				if (this.next[i] != null) {
					String part = this.next[i].getFirstWord(minSize - 1);
					if (part != null) {
						word += part;
						break;
					}
				}
			}
		} else {
			return null;
		}

		return word;
	}

}